#include "sdecoder.hh"
#include <iostream>



SDecoder::SDecoder()
  : m_Button_Quit(Gtk::Stock::QUIT),
    m_Button_Decode(Gtk::Stock::CONVERT),
    m_Button_Clear(Gtk::Stock::CLEAR)
{
  selected_RB_id = 0;
  f1tdc          = NULL;
  v792qdc        = NULL;
  sis3801scaler  = NULL;
  vqwkadc        = NULL;


  set_title("sDecoder v0.2 - by jhlee");
  set_border_width(4);
  set_default_size(480,320);

  add(m_VBox);

  m_Entry_Label.set_justify(Gtk::JUSTIFY_LEFT);
  m_Entry_Label.set_text("Type HEX number (eg. 0x241211c0)   ");

  m_Entry.set_max_length(10); //only 32 Bit data include 0x
  m_Entry.set_text("0x55ba34d6");
  m_Entry.select_region(0,m_Entry.get_text_length());
  m_Entry.set_has_frame(true);

  m_Entry.signal_activate().connect(sigc::mem_fun(*this,
						   &SDecoder::on_button_decode)
				     );
  m_HBox_Entry.pack_start(m_Entry_Label, Gtk::PACK_SHRINK);
  m_HBox_Entry.pack_start(m_Entry,       Gtk::PACK_SHRINK);
 
  m_VBox.pack_start(m_HBox_Entry, Gtk::PACK_SHRINK);
  m_VBox.pack_start(m_Table,      Gtk::PACK_SHRINK);

 
  m_RButton[0].set_label("F1TDC");
  m_RButton[1].set_label("V792");
  m_RButton[2].set_label("SIS3801");
  m_RButton[3].set_label("VQWK");

  Gtk::RadioButton::Group group = m_RButton[0].get_group();
  
  unsigned short rb_id;
  for(rb_id = 1; rb_id<4; rb_id++) {
    m_RButton[rb_id].set_group(group);
  }
  
  unsigned short pos =0;
  unsigned short i,j;
  
  for( i=0; i<1; i++) {;
    for( j=0; j<4; j++) {;;  
      m_Table.attach(m_RButton[pos],   j, j+1, i, i+1, 
		     Gtk::FILL | Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND, 4,4 );
      pos++;
    }
  }
  
  //   g_signal_connect(G_OBJECT(rbutton[0]), "toggled", G_CALLBACK(toggle_button_cb),  GUINT_TO_POINTER(0));
  
  m_RButton[0].signal_toggled().connect(sigc::bind<0>
					(
					 sigc::mem_fun(*this, &SDecoder::on_button_radio),
					 0
					 )
					);
  
  // See http://library.gnome.org/devel/gtkmm-tutorial/unstable/sec-multi-item-containers.html.en#sec-helloworld2
  for(rb_id = 1; rb_id<4; rb_id++) {
    m_RButton[rb_id].signal_toggled().connect(sigc::bind<0>
					      (
					       sigc::mem_fun(*this, &SDecoder::on_button_radio),
					       rb_id
					       )
					      );
  }
  
  m_RButton[0].set_active();
  
  m_ScrolledWindow.add(m_TextView);
  m_ScrolledWindow.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
  
  m_VBox.pack_start(m_ScrolledWindow);
  m_VBox.pack_start(m_ButtonBox, Gtk::PACK_SHRINK);
  

  m_ButtonBox.pack_start(m_Button_Decode, Gtk::PACK_SHRINK);
  m_ButtonBox.pack_start(m_Button_Clear,  Gtk::PACK_SHRINK);
  m_ButtonBox.pack_start(m_Button_Quit,   Gtk::PACK_SHRINK);
  
  m_ButtonBox.set_border_width(5);
  m_ButtonBox.set_spacing(5);
  m_ButtonBox.set_layout(Gtk::BUTTONBOX_END);
 
  m_Button_Decode.signal_clicked().connect(sigc::mem_fun(*this,
							 &SDecoder::on_button_decode)
					   );
  m_Button_Clear.signal_clicked().connect(sigc::mem_fun(*this,
							&SDecoder::on_button_clear)
					  );
  m_Button_Quit.signal_clicked().connect(sigc::mem_fun(*this,
						       &SDecoder::on_button_quit)
					 );
 
  m_refTextBuffer = Gtk::TextBuffer::create();
  
  show_all_children();
}

SDecoder::~SDecoder()
{
  ClearPointer();
}

const char* SDecoder::name[4]={"F1TDC","V792","SIS3801", "VQWK"};

void 
SDecoder::on_button_decode()
{
  //  printf("%s is selected.\n", name[GetSelectedID()]);
  //  PrintLog(name[GetSelectedID()]);
  //  PrintLog(m_Entry.get_text());

  std::string  output;
  
  // check the existing pointer for VME module
  // if it is, delete, and reinitialize them.

  ClearPointer();
  output.clear();

  if(GetSelectedID() == 0) {
    f1tdc = new F1TDC(m_Entry.get_text().c_str());
    output = f1tdc->GetDecodedData();
    
  }
  else if (GetSelectedID() == 1) {
    v792qdc = new V792(m_Entry.get_text().c_str());
    output = v792qdc->GetDecodedData();
  }
  else if (GetSelectedID() == 2) {
    sis3801scaler = new SIS3801(m_Entry.get_text().c_str());
    output = sis3801scaler->GetDecodedData();
  }
  else if (GetSelectedID() == 3) {
    vqwkadc = new VQWK(m_Entry.get_text().c_str());
    output = vqwkadc->GetDecodedData();
  }
  else {
  }
  
  if(!output.empty()) {
    std::cout << output << std::endl;
    PrintLog(output);
  }
  else {
    std::cout << "The input is not a word for " << name[GetSelectedID()] << std::endl;
  }
  return;
}

void 
SDecoder::on_button_clear()
{
  m_Entry.set_text("");
  m_refTextBuffer->set_text("");
  m_TextView.set_buffer(m_refTextBuffer);
  
  return;
}

void 
SDecoder::on_button_quit()
{
  hide(); //Closes the main window to stop the Gtk::Main::run().
  return;
}

void 
SDecoder::on_button_radio(int id)
{
  bool local_debug = false;  
  if ( m_RButton[id].get_active() ) {
    SetSelectedID(id);
    std::string input;
    if      (GetSelectedID() == 0) input = "0x55ba34d6";
    else if (GetSelectedID() == 1) input = "0x08134078"; // data 
    else if (GetSelectedID() == 2) input = "0xc90000ce"; // data 
    else if (GetSelectedID() == 3) input = ""; // data 
    else    ;


    m_Entry.set_text(input);
    if(local_debug) printf("Selected %d\n", GetSelectedID());
  }
  return;
}

// SIS3801
// 0x00200020  0xc00000cd  0xc10000c2  0xc20000cf  0xc30000ce  
// 0xc40000cf  0xc50000cd  0xc60000d0  0xc70000cd  0xc80000cd  
// 0xc90000ce  0xca0000ce  0xcb0000ce  0xcc0000cf  0xcd0000ca  
// 0xce0000cf  0xcf0000ce

// V792 data stream
// 0xda00adc0  0x00000022  0x0a002000  0x080040d8  0x0810408c
// 0x080140ad  0x08114068  0x080240d7  0x0812406b  0x080340fc  
// 0x08134078  0x0804410d  0x0814408e  0x080540f6  0x08154079  
// 0x08064102  0x0816407f  0x080740e0  0x08174084  0x080840b4  
// 0x08184070  0x08094103  0x081947fe  0x080a40dc  0x081a4062  
// 0x080b40b8  0x081b4034  0x080c40d1  0x081c4087  0x080d40f6  
// 0x081d4025  0x080e4104  0x081e4072  0x080f40f5  0x081f4037  0x0c000000  

void 
SDecoder::on_my_insert_at_cursor(Glib::ustring str)
{
  m_refTextBuffer->set_text(str);
  m_TextView.set_buffer(m_refTextBuffer);
  return;
}


void 
SDecoder::PrintLog(const std::string &log) { 
  m_refTextBuffer->insert(m_refTextBuffer->end(), log+"\n"); 
  m_TextView.set_buffer(m_refTextBuffer);
  return;
} 


void
SDecoder::ClearPointer() 
{
  if(f1tdc)         { delete f1tdc;         f1tdc         = NULL;}
  if(v792qdc)       { delete v792qdc;       v792qdc       = NULL;}
  if(sis3801scaler) { delete sis3801scaler; sis3801scaler = NULL;}
  if(vqwkadc)       { delete vqwkadc;       vqwkadc       = NULL;}
}
